package com.ibeeking.found.file.rest.service.impl;

import com.ibeeking.found.common.constants.GlobalConstant;
import com.ibeeking.found.common.utils.UserUtils;
import com.ibeeking.found.file.rest.service.ISourceGroupService;
import com.ibeeking.found.file.rest.service.ISourceService;
import com.ibeeking.found.file.service.common.bo.SourceBO;
import com.ibeeking.found.file.service.common.constants.SourceConstant;
import com.ibeeking.found.file.service.common.dos.SourceGroupDO;
import com.ibeeking.found.file.service.common.param.SourceGroupParam;
import com.ibeeking.found.file.service.common.query.SourceGroupQuery;
import com.ibeeking.found.file.service.common.util.DoUtils;
import com.ibeeking.found.file.service.common.vo.SourceGroupListVO;
import com.ibeeking.found.file.service.common.vo.SourceGroupVO;
import com.ibeeking.found.file.service.mapper.SourceGroupMapper;
import com.ibeeking.nematos.exception.BusinessException;
import com.ibeeking.nematos.utils.bean.BeanUtil;
import com.ibeeking.nematos.utils.data.Collections3;
import com.ibeeking.nematos.utils.data.StringUtils;
import com.ibeeking.nematos.utils.data.TreeFastUtils;
import com.ibeeking.nematos.utils.json.JsonUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;


/**
 * @ClassName SourceGroupServiceImpl
 * @Description
 * @Author ibeeking
 * @Date 2021-02-23 15:10
 **/
@Service
public class SourceGroupServiceImpl extends ServiceImpl<SourceGroupMapper, SourceGroupDO> implements ISourceGroupService {

    @Resource
    private SourceGroupMapper sourceGroupMapper;

    @Resource
    private ISourceService goodsSourceServiceImpl;

    @Override
    public List<SourceGroupListVO> list(SourceGroupQuery sourceGroupQuery){
        LambdaQueryWrapper<SourceGroupDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(sourceGroupQuery.getShopId()!=null, SourceGroupDO::getShopId, sourceGroupQuery.getShopId())
                .eq(SourceGroupDO::getMerchantsBusiness, sourceGroupQuery.getMerchantsBusiness())
                .eq(SourceGroupDO::getType, sourceGroupQuery.getType())
                .like(StringUtils.isNotBlank(sourceGroupQuery.getName()), SourceGroupDO::getName, sourceGroupQuery.getName())
                .orderByDesc(SourceGroupDO::getSystemStatus)
                .orderByAsc(SourceGroupDO::getSort)
                .orderByDesc(SourceGroupDO::getCreateTime);
        queryWrapper.or(Wrapper-> Wrapper.eq(SourceGroupDO::getSystemStatus,1));
        List<SourceGroupDO> sourceGroupDOS = sourceGroupMapper.selectList(queryWrapper);
        List<SourceGroupListVO> sourceGroupListVOS = JsonUtils.jsonToList(sourceGroupDOS, SourceGroupListVO.class);
        for (SourceGroupListVO sourceGroupListVO : sourceGroupListVOS) {
            SourceBO sourceBO = new SourceBO();
            if(sourceGroupQuery.getShopId()!=null){
                sourceBO.setId(sourceGroupListVO.getId());
                sourceBO.setMerchantsBusiness(1);
                sourceBO.setType(sourceGroupQuery.getType());
                sourceBO.setShopId(sourceGroupQuery.getShopId());
            }else{
                sourceBO.setId(sourceGroupListVO.getId());
                sourceBO.setMerchantsBusiness(2);
                sourceBO.setType(sourceGroupQuery.getType());

            }
            sourceGroupListVO.setSourceCount(goodsSourceServiceImpl.listCountByParentIdAndType(sourceBO));
        }
        sourceGroupListVOS.forEach(sourceGroupListVO -> {
            if(SourceConstant.all_parentId.equals(sourceGroupListVO.getId())){
                sourceGroupListVO.setSourceCount(sourceGroupListVOS.stream().mapToInt(SourceGroupListVO::getSourceCount).sum());
            }
        });
        return TreeFastUtils.listToTree(sourceGroupListVOS, GlobalConstant.PARENT_ID);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(SourceGroupParam sourceGroupParam){
        SourceGroupDO sourceGroupDO = BeanUtil.convertBean(sourceGroupParam, SourceGroupDO.class);
        sourceGroupDO.setCreateBy(UserUtils.getUserId());
        sourceGroupDO.setCreateTime(LocalDateTime.now());
        sourceGroupDO.setModifyTime(LocalDateTime.now());
        LambdaQueryWrapper<SourceGroupDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(sourceGroupParam.getShopId()!=null, SourceGroupDO::getShopId, sourceGroupParam.getShopId())
                    .eq(SourceGroupDO::getMerchantsBusiness, sourceGroupParam.getMerchantsBusiness())
                    .eq(SourceGroupDO::getType, sourceGroupParam.getType())
                    .eq(SourceGroupDO::getName, sourceGroupParam.getName());
        List<SourceGroupDO> repeatList = sourceGroupMapper.selectList(queryWrapper);
        if(Collections3.isNotEmpty(repeatList)){
            throw new BusinessException("分组名重复");
        }
        return sourceGroupMapper.insert(sourceGroupDO)>0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean modify(SourceGroupParam sourceGroupParam){
        SourceGroupDO sourceGroupDO1 = sourceGroupMapper.selectById(sourceGroupParam.getId());

        if(sourceGroupDO1.getSystemStatus().equals(1)){
            throw new BusinessException("系统分组禁止修改");
        }
        SourceGroupDO sourceGroupDO = BeanUtil.convertBean(sourceGroupParam, SourceGroupDO.class);
        sourceGroupDO.setModifyBy(UserUtils.getUserId());
        sourceGroupDO.setModifyTime(LocalDateTime.now());
        List<SourceGroupDO> repeatList = DoUtils.getRepeatList(sourceGroupDO, sourceGroupMapper, sourceGroupParam.getId(), sourceGroupParam.getName(),null);
        repeatList = repeatList.stream().filter(node -> node.getId().equals(sourceGroupParam.getId())).collect(Collectors.toList());
        if(Collections3.isNotEmpty(repeatList)){
            throw new BusinessException("分组名重复");
        }
        return sourceGroupMapper.updateById(sourceGroupDO)>0;
    }

    @Override
    public SourceGroupVO view(Long id){
        SourceGroupDO sourceGroupDO = sourceGroupMapper.selectById(id);
        return BeanUtil.convertBean(sourceGroupDO, SourceGroupVO.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean del(Long id){
        SourceGroupDO sourceGroupDO = sourceGroupMapper.selectById(id);
        if(sourceGroupDO.getSystemStatus().equals(1)){
            throw new BusinessException("系统分组禁止删除");
        }
        return this.delMethod(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean delMethod(Long id) {
        LambdaQueryWrapper<SourceGroupDO> queryWrapper= new LambdaQueryWrapper<>();
        queryWrapper.eq(SourceGroupDO::getParentId, id);
        List<SourceGroupDO> sourceGroupDOS = sourceGroupMapper.selectList(queryWrapper);
        if(Collections3.isNotEmpty(sourceGroupDOS)){
            for (SourceGroupDO sourceGroupDO : sourceGroupDOS) {
                this.del(sourceGroupDO.getId());
            }
        }
        //删除分组将素材修改到未分组
        goodsSourceServiceImpl.modifyParentId(id);
        return sourceGroupMapper.deleteById(id)>0;
    }
}